home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_10_08 / cmenu14.exe / CMENU3.C < prev    next >
C/C++ Source or Header  |  1992-05-22  |  5KB  |  220 lines

  1. /************************************************************
  2.  *    Program: CMENU Menu Compiler
  3.  *  Module: cmenu3.c
  4.  *        Menu Compiler:
  5.  *        Token Processing Functions
  6.  *    Written by: Leor Zolman, 7/91
  7.  ************************************************************/
  8.  
  9. #include "cmenu.h"
  10. #include "ccmenu.h"
  11.  
  12. #if __STDC__
  13. #pragma hdrstop
  14. #endif
  15.  
  16. #include <ctype.h>
  17.  
  18. static int unget_flag = FALSE;
  19. static int unget_token;
  20. static char unget_tparam[MAX_CMD];
  21. static int unget_vparam;
  22.  
  23. static int quoted_text;
  24.  
  25. #if __STDC__
  26. char *getword(void);
  27. int matchkey(char *);
  28. #else
  29. char *getword();
  30. int matchkey();
  31. #endif
  32.  
  33. /************************************************************
  34.  * ungettok():
  35.  *    Push a token back into the input stream, to
  36.  *    be returned by the following call to gettok().
  37.  *    Only one level of push-back is supported; any attempt to
  38.  *    push back a token when there is already one pushed back
  39.  *    draws an "internal error" diagnostic.
  40.  ************************************************************/
  41.  
  42. Void ungettok(tok)
  43. int tok;
  44. {
  45.     if (unget_flag)        /* can't "unget" more than 1 item! */
  46.         fatalerr("internal error: ungettok() overflow");
  47.     
  48.     unget_flag = TRUE;
  49.     unget_token = tok;
  50.     unget_vparam = vparam;
  51.     strcpy(unget_tparam, tparam);
  52.     return;
  53. }
  54.  
  55.  
  56. /************************************************************
  57.  * gettok():
  58.  *    Read a token from the source input stream.
  59.  *    If the token is a reserved word, the appropriate token
  60.  *        value is returned.
  61.  *    If the token is a string, the global "tparam" is set
  62.  *        to the text of the string. White space within the
  63.  *        string is only recognized if double quote ("...")
  64.  *        characters are used to delimit the string.
  65.  *        T_STRING is returned.
  66.  *    If the token is a numeric value, the global "vparam"
  67.  *        is set to the integer value specified, and
  68.  *        T_VALUE is returned.
  69.  *    Returns T_EOF on end-of-file.
  70.  ************************************************************/
  71.  
  72. int gettok()
  73. {
  74.     register c;
  75.     char nexttok[MAX_CMD];
  76.     char *wordp;
  77.     
  78.     if (unget_flag)        /* was a token "pushed back"?    */
  79.     {            /* yes. set the pushed-back values and    */
  80.         vparam = unget_vparam;            /* attributes    */
  81.         strcpy(tparam, unget_tparam);    /* clear the    */
  82.         unget_flag = FALSE;                /* flag            */
  83.         return unget_token;        /* return pushed token    */
  84.     }
  85.     
  86.     *tparam = '\0';                    /* clear parameter    */
  87.     vparam = 0;                        /* value registers    */
  88.  
  89.     if (!*(wordp = getword()))        /* get a token.        */
  90.         return token = T_EOF;        /* End of file        */
  91.     
  92.     if (quoted_text)                /* string enclosed    */
  93.     {                                /* in quotes?        */
  94.         strcpy(tparam, wordp);
  95.         return T_STRING;
  96.     }
  97.  
  98.     if (!strcmp(wordp, ":"))        /* colon is special    */
  99.         return T_COLON;                /* (non-alphabetic)    */
  100.  
  101.     if (c = matchkey(wordp))        /* reserved word?    */
  102.         return c;                    /* yes, just return    */
  103.  
  104.     if (isdigit(*wordp))            /* handle numeric value    */
  105.     {
  106.         vparam = atoi(wordp);
  107.         return T_VALUE;
  108.     }
  109.     else
  110.     {
  111.         strcpy(tparam, wordp);
  112.         return T_STRING;
  113.     }
  114. }
  115.  
  116.  
  117. /************************************************************
  118.  * getword():
  119.  *    Read the next syntactic object from the input stream,
  120.  *    and return a pointer to it.
  121.  *    Return pointer to a null string on EOF.
  122.  *    If object is a quoted string, drop the quotes and
  123.  *        set the quoted_text flag (preserve whitespace).
  124.  *    Otherwise strip all whitespace, commas and comments,
  125.  *        return pointer to next word/number.
  126.  *  Track current line number by incrementing lineno
  127.  *        on each newline encountered.
  128.  ************************************************************/
  129.  
  130. char *getword()
  131. {
  132.     static char tok[MAX_CMD];
  133.     char quote_char;
  134.     register c,i;
  135.     
  136.     quoted_text = FALSE;
  137.     *tok = '\0';
  138.  
  139.     while ((c = getc(fp)) != EOF)
  140.     {
  141.         if (c == '\n')                /* bump line number if    */
  142.             lineno++;                /* newline encountered    */
  143.         
  144.         if (isspace(c))                /* skip all whitespace    */
  145.             continue;
  146.  
  147.         if (c == ',' || c == ';')    /* legal separators: ,; */
  148.             continue;
  149.                 
  150.         if (c == ':')                /* special case: colon    */
  151.             return ":";
  152.         
  153.         if (c == '#')                /* process comment        */
  154.         {                        /* wait for newline or EOF    */
  155.             while(c = getc(fp))
  156.             {
  157.                 if (c == EOF)
  158.                     break;
  159.                 if (c == '\n')
  160.                 {
  161.                     lineno++;
  162.                     break;
  163.                 }
  164.             }
  165.             continue;                /* then get next token    */
  166.         }
  167.         
  168.         if (c == '"' || c == '\'')    /* quoted string?        */
  169.         {
  170.             quoted_text = TRUE;
  171.             quote_char = c;
  172.             for (i = 0; ;i++)
  173.             {
  174.                 switch (c = getc(fp))
  175.                 {
  176.                     case '\n':
  177.                         fatalerr("Unterminated string");
  178.                         return NULL;
  179.                         
  180.                     case EOF:
  181.                         fatalerr("Unterminated string (line %d)",
  182.                                 lineno);
  183.                         return NULL;
  184.                     
  185.                     case '"':
  186.                     case '\'':
  187.                         if (c == quote_char)
  188.                         {
  189.                             tok[i] = '\0';
  190.                             return tok;
  191.                         }
  192.  
  193.                     default:
  194.                         if (i == MAX_CMD)
  195.                         {
  196.                             tok[i - 1] = '\0';
  197.                             fatalerr("String too long (max %d chars)",
  198.                                 MAX_CMD);
  199.                             return NULL;
  200.                         }
  201.                         tok[i] = c;
  202.                 }
  203.             }
  204.         }
  205.         
  206.         tok[0] = c;
  207.         for (i = 1; (c = getc(fp)) != EOF; i++)
  208.             if (isspace(c) || c == ';' || c == ','
  209.                     || c == ':')
  210.                 break;
  211.             else
  212.                 tok[i] = tolower(c);
  213.         tok[i] = '\0';
  214.         ungetc(c, fp);
  215.         break;
  216.     }
  217.     return tok;
  218. }
  219.  
  220.